package com.fengmi.aop.dot;


import com.fengmi.interceptor.UserInfoInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
@SuppressWarnings({"unused"})
@Slf4j
public class DotLogAspect {

    @Pointcut("@annotation(com.fengmi.aop.dot.DotLog)")
    public void point() {

    }



    @AfterReturning("point()")
    public void runBeforeTestMethod(JoinPoint joinPoint) {
        try {
            String des = getDes(joinPoint);
            String operateType = getOperateType(joinPoint);

            log.info("用户{},时间{},操作{}描述{}", UserInfoInterceptor.getUserInfo().getAccount(),new Date(),operateType,des);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }




    private String getDes(JoinPoint joinPoint) throws ClassNotFoundException {
        //获取被代理对象名称
        String targetName = joinPoint.getTarget().getClass().getName();
        //获取目标方法名称
        String methodName = joinPoint.getSignature().getName();
        //获取传入目标方法的参数对象
        Object[] arguments = joinPoint.getArgs();
        //获取class对象
        Class targetClass = Class.forName(targetName);
        //获取对象中的所有方法
        Method[] methods = targetClass.getMethods();
        String des = "";
        //下面是进行匹配，方法名和目标方法名相同，且参数相同，则获取注解内的相应参数，用来进行日志记录
        for (Method method : methods) {
            if (method.getName().equals(methodName)){
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length){
                    des = method.getAnnotation(DotLog.class).description();
                    break;
                }
            }
        }
        return des;
    }

    private String getOperateType(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String operateType = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)){
                if (method.getParameterTypes().length == args.length){
                    operateType = method.getAnnotation(DotLog.class).operateType();
                    break;
                }
            }
        }
        return operateType;
    }


}

